home *** CD-ROM | disk | FTP | other *** search
/ Macwelt 1 / Macwelt DVD 1.toast / Web-Publishing / HTML-Editoren / Alpha ƒ / Tcl / Modes / HTML and CSS Modes / cssGetProperties.tcl < prev    next >
Encoding:
Text File  |  2001-01-15  |  20.6 KB  |  767 lines

  1. ## -*-Tcl-*-
  2.  # ###################################################################
  3.  #  CSS mode - tools for editing CSS documents
  4.  # 
  5.  #  FILE: "cssGetProperties.tcl"
  6.  #                                    created: 00-01-02 00.26.20 
  7.  #                                last update: 01-01-15 20.23.50 
  8.  #  Author: Johan Linde
  9.  #  E-mail: <alpha_www_tools@go.to>
  10.  #     www: <http://go.to/alpha_www_tools>
  11.  #  
  12.  # Version: 2.0
  13.  # 
  14.  # Copyright 1997-2001 by Johan Linde
  15.  #  
  16.  # This program is free software; you can redistribute it and/or modify
  17.  # it under the terms of the GNU General Public License as published by
  18.  # the Free Software Foundation; either version 2 of the License, or
  19.  # (at your option) any later version.
  20.  # 
  21.  # This program is distributed in the hope that it will be useful,
  22.  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  23.  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24.  # GNU General Public License for more details.
  25.  # 
  26.  # You should have received a copy of the GNU General Public License
  27.  # along with this program; if not, write to the Free Software
  28.  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  29.  # 
  30.  # ###################################################################
  31.  ##
  32.  
  33. #===============================================================================
  34. # This file contain procs for parsing the property value in a document
  35. # and get a default value for the property dialog.
  36. # For each type of property there is a proc
  37. # css::GetProperties<type>
  38. #===============================================================================
  39.  
  40. #===============================================================================
  41. # ◊◊◊◊ Getting properties ◊◊◊◊ #
  42. #===============================================================================
  43.  
  44. proc css::GetProperties {group v r0 r1 im et} {
  45.     upvar $v val $r0 removePos0 $r1 removePos1 $im important $et errorText
  46.     global css::Property css::Descriptor css::IsDescriptor
  47.     
  48.     # Find interval to search in.
  49.     if {[catch {matchIt "\}" [getPos]} start]} {
  50.         if {![catch {search -s -f 0 -m 0 -r 0 "\}" [getPos]} r0] ||
  51.         ![catch {search -s -f 1 -i 1 -m 0 -r 0 "<STYLE([ \t\r\n]+[^<>]*>|>)" [getPos]} r0]} {
  52.             set start [lindex $r0 1]
  53.         } else {
  54.             set start [minPos]
  55.         }
  56.     }
  57.     if {[catch {matchIt "\{" [getPos]} end]} {
  58.         set rbrace [maxPos]
  59.         set style [maxPos]
  60.         if {![catch {search -s -f 1 -m 0 -r 0 "\{" [getPos]} r0]} {
  61.             set rbrace [lineStart [lindex $r0 0]]
  62.         }
  63.         if {![catch {search -s -f 1 -i 1 -m 0 -r 0 "</STYLE>" [getPos]} r0]} {
  64.             set style [lindex $r0 0]
  65.         }
  66.         if {[pos::compare $rbrace < $style]} {
  67.             set end $rbrace
  68.         } else {
  69.             set end $style
  70.         }
  71.     }
  72.     if {${css::IsDescriptor}} {
  73.         set gprop [set css::Descriptor($group)]
  74.     } else {
  75.         set gprop [set css::Property($group)]
  76.     }
  77.     # Find all properties
  78.     if {$gprop == "group" || $gprop == "border"} {
  79.         css::GetPropertiesgroup $start $end $group val removePos0 removePos1 important errorText
  80.     } else {
  81.         set propValue [css::FindProperty $start $end $group removePos0 removePos1 important]
  82.         eval css::GetProperties$gprop $group propValue val
  83.         if {[llength $propValue]} {
  84.             lappend errorText "$group: $propValue"
  85.         }
  86.     }
  87. }
  88.  
  89. proc css::GetPropertiesgroup {start end group v r0 r1 im et} {
  90.     upvar $v val $r0 removePos0 $r1 removePos1 $im important $et errorText
  91.     
  92.     global css::ExpandProps css::Shorthand css::UseShort css::Group css::IsDescriptor 
  93.     global css::InheritAll css::Descriptor css::Property
  94.     # If shorthand property, look for a shorthand definition.
  95.     if {[set css::Shorthand($group)]} {
  96.         set groupValue [css::FindProperty $start $end $group removePos0 removePos1 important]
  97.         if {[string tolower $groupValue] == "inherit"} {
  98.             set css::InheritAll 1
  99.         } elseif {$groupValue != ""} {
  100.             eval [set css::ExpandProps($group)] $group [list $groupValue] propValue errorText
  101.         }
  102.     }
  103.     # Find all properties belonging to the group.
  104.     foreach prop [set css::Group($group)] {
  105.         # Trick for border
  106.         set prop1 $prop
  107.         if {$group == "border"} {regsub -- "-top-" $prop "-" prop1}
  108.         if {![info exists propValue($prop1)]} {set propValue($prop1) ""}
  109.         if {${css::IsDescriptor}} {
  110.             set p [set css::Descriptor($prop)]
  111.         } else {
  112.             set p [set css::Property($prop)]
  113.         }
  114.         set pval [css::FindProperty $start $end $prop1 removePos0 removePos1 important]
  115.         if {$pval != ""} {
  116.             set propValue($prop1) $pval
  117.             set css::UseShort 0
  118.         }
  119.         set pval $propValue($prop1)
  120.         eval css::GetProperties$p $prop pval val
  121.         if {[llength $pval]} {
  122.             lappend errorText "$prop1: $pval"
  123.         }
  124.     }
  125. }
  126.  
  127. proc css::FindProperty {start end prop r0 r1 im} {
  128.     upvar $r0 remove0 $r1 remove1 $im important
  129.     global css::CommentRegexp
  130.     set propValue ""
  131.     set st0 $start
  132.     while {1} {
  133.         if {[catch {search -s -f 1 -i 1 -m 0 -r 1 -l $end "(\[ \t\r\n\]+|;|\{)$prop\[ \t\r\n\]*:" $st0} res]} {
  134.             break
  135.         } elseif {![catch {search -s -f 1 -i 1 -m 0 -r 0 -l $end "\;" [lindex $res 1]} res1]} {
  136.             if {![css::IsInComment [lindex $res 0]]} {
  137.                 set propValue [string trim [getText [lindex $res 1] [pos::math [lindex $res1 1] - 1]]]
  138.                 set r00 [lindex $res 0]
  139.                 if {[lookAt $r00] == ";" || [lookAt $r00] == "\{"} {set r00 [pos::math $r00 + 1]}
  140.                 lappend remove0 $r00 
  141.                 lappend remove1 [lindex $res1 1]
  142.                 break
  143.             } else {
  144.                 set st0 [lindex $res1 1]
  145.             }
  146.         } else {
  147.             if {![css::IsInComment [lindex $res 0]]} {
  148.                 set propValue [string trim [getText [lindex $res 1] $end]]
  149.                 set r00 [lindex $res 0]
  150.                 if {[lookAt $r00] == ";" || [lookAt $r00] == "\{"} {set r00 [pos::math $r00 + 1]}
  151.                 lappend remove0 $r00 
  152.                 lappend remove1 $end
  153.                 break
  154.             } else {
  155.                 set st0 [lindex $res1 1]
  156.             }
  157.         }
  158.     }
  159.     regsub -all ${css::CommentRegexp} $propValue "" propValue
  160.     if {[regsub -nocase {![ \t\r]*important} $propValue {} propValue]} {set important($prop) 1}
  161.     return [string trim $propValue]
  162. }
  163.  
  164. # choices
  165. proc css::GetPropertieschoices {prop pval v} {
  166.     upvar $pval pvalue $v val
  167.     global css::Choices
  168.     css::GetChoicesProp [set css::Choices($prop)] pvalue val
  169. }
  170.  
  171. # color
  172. proc css::GetPropertiescolor {prop pval v} {
  173.     upvar $pval pvalue $v val
  174.     css::GetChoicesProp "" pvalue val
  175.     css::GetColorProp pvalue val
  176. }
  177.  
  178. # url
  179. proc css::GetPropertiesurl {prop pval v} {
  180.     upvar $pval pvalue $v val
  181.     css::GetChoicesProp "" pvalue val
  182.     css::GetUrlProp pvalue val
  183. }
  184.  
  185. # family = like font-family and voice-family
  186. proc css::GetPropertiesfamily {prop pval v} {
  187.     upvar $pval pvalue $v val
  188.     if {[string tolower $pvalue] == "inherit"} {
  189.         lappend val inherit "" 0
  190.     } else {
  191.         lappend val " " $pvalue 0
  192.     }
  193.     set pvalue ""    
  194. }
  195.  
  196. # integer
  197. proc css::GetPropertiesinteger {prop pval v} {
  198.     upvar $pval pvalue $v val
  199.     css::GetChoicesProp "" pvalue val
  200.     css::GetNumberNoUnit $prop pvalue val 0 1
  201. }
  202.  
  203. # number
  204. proc css::GetPropertiesnumber {prop pval v} {
  205.     upvar $pval pvalue $v val
  206.     css::GetChoicesProp "" pvalue val
  207.     css::GetNumberNoUnit $prop pvalue val 0 0
  208. }
  209.  
  210. # nlpc = number, length, percentage, or choices
  211. proc css::GetPropertiesnlpc {prop pval v} {
  212.     upvar $pval pvalue $v val
  213.     css::GetNumChoices $prop pvalue val length 1 1 0
  214. }
  215.  
  216. # lpc = length, percentage, or choices
  217. proc css::GetPropertieslpc {prop pval v} {
  218.     upvar $pval pvalue $v val
  219.     css::GetNumChoices $prop pvalue val length 1 0 0
  220. }
  221.  
  222. # npc = number, percentage, or choices
  223. proc css::GetPropertiesnpc {prop pval v} {
  224.     upvar $pval pvalue $v val
  225.     css::GetNumChoices $prop pvalue val number 1 1 1
  226. }
  227.  
  228. # lc = length or choices
  229. proc css::GetPropertieslc {prop pval v} {
  230.     upvar $pval pvalue $v val
  231.     css::GetNumChoices $prop pvalue val length 0 0 0
  232. }
  233.  
  234. # ac = angle or choices
  235. proc css::GetPropertiesac {prop pval v} {
  236.     upvar $pval pvalue $v val
  237.     css::GetNumChoices $prop pvalue val angle 0 0 0
  238. }
  239.  
  240. # fc = frequency or choices
  241. proc css::GetPropertiesfc {prop pval v} {
  242.     upvar $pval pvalue $v val
  243.     css::GetNumChoices $prop pvalue val frequency 0 0 0
  244. }
  245.  
  246. # cc = color or choices
  247. proc css::GetPropertiescc {prop pval v} {
  248.     upvar $pval pvalue $v val
  249.     css::GetPropertieschoices $prop pvalue val
  250.     css::GetColorProp pvalue val
  251. }
  252.  
  253. # uc = url or choices
  254. proc css::GetPropertiesuc {prop pval v} {
  255.     upvar $pval pvalue $v val
  256.     css::GetPropertieschoices $prop pvalue val
  257.     css::GetUrlProp pvalue val
  258. }
  259.  
  260. # lp = length or percentage
  261. proc css::GetPropertieslp {prop pval v} {
  262.     upvar $pval pvalue $v val
  263.     css::GetChoicesProp "" pvalue val
  264.     css::GetNumber $prop pvalue val length 1 0 0
  265. }
  266.  
  267. # tp = time or percentage
  268. proc css::GetPropertiestp {prop pval v} {
  269.     upvar $pval pvalue $v val
  270.     css::GetChoicesProp "" pvalue val
  271.     css::GetNumber $prop pvalue val time 1 0 0
  272. }
  273.  
  274. # ic = integer or choices
  275. proc css::GetPropertiesic {prop pval v} {
  276.     upvar $pval pvalue $v val
  277.     css::GetPropertieschoices $prop pvalue val
  278.     css::GetNumberNoUnit $prop pvalue val 0 1
  279. }
  280.  
  281. # nc = number or choices
  282. proc css::GetPropertiesnc {prop pval v} {
  283.     upvar $pval pvalue $v val
  284.     css::GetPropertieschoices $prop pvalue val
  285.     css::GetNumberNoUnit $prop pvalue val 0 0
  286. }
  287.  
  288. # border
  289. # No proc needed!
  290.  
  291.  
  292. # clip
  293. proc css::GetPropertiesclip {prop pval v} {
  294.     upvar $pval pvalue $v val
  295.     global css::Choices
  296.     css::GetChoicesProp [set css::Choices($prop)] pvalue val
  297.     if {![regexp {^rect\(([^,]+),([^,]+),([^,]+),([^,]+)\)$} [string tolower $pvalue] "" top right bottom left]} {
  298.         lappend val 0 "" "" 0 "" "" 0 "" "" 0 "" ""
  299.         return
  300.     }
  301.     foreach side {top right bottom left} {
  302.         set $side [string trim [set $side]]
  303.         if {[set $side] == "auto"} {
  304.             set $side ""
  305.             lappend val 1
  306.         } else {
  307.             lappend val 0
  308.         }
  309.         css::GetNumber clip $side val length 0 0 0
  310.         lappend pv [set $side]
  311.     }
  312.     set pvalue [join $pv]
  313. }
  314.  
  315. # quotes
  316. proc css::GetPropertiesquotes {prop pval v} {
  317.     upvar $pval pvalue $v val
  318.     css::GetPropertieschoices $prop pvalue val
  319.     lappend val "" "" 0 $pvalue
  320.     if {$pvalue != "" && [regexp {^(('[^']+'|\"[^\"]+\")[ \t\r\n]+('[^']+'|\"[^\"]+\")[ \t\r\n]+)+$} "$pvalue "]} {
  321.         set pvalue ""
  322.     }
  323. }
  324.  
  325. # counter
  326. proc css::GetPropertiescounter {prop pval v} {
  327.     upvar $pval pvalue $v val
  328.     css::GetPropertieschoices $prop pvalue val
  329.     lappend val $pvalue
  330.     if {$pvalue != "" && [regexp {^([^-0-9][^ \t\r\n]*([ \t\r\n]+[-\+]?[0-9]+)?[ \t\r\n]+)+$} "$pvalue "]} {
  331.         set pvalue ""
  332.     }
  333. }
  334.  
  335. # size
  336. proc css::GetPropertiessize {prop pval v} {
  337.     upvar $pval pvalue $v val
  338.     css::GetPropertieschoices $prop pvalue val
  339.     for {set i 0} {$i < 2} {incr i} {
  340.         set pv [lindex $pvalue $i]
  341.         css::GetNumber $prop pv val length 0 0 0
  342.         lappend newpv $pv
  343.     }
  344.     set pvalue [join [concat $newpv [lrange $pvalue 2 end]]]
  345. }
  346.  
  347. # content
  348. proc css::GetPropertiescontent {prop pval v} {
  349.     upvar $pval pvalue $v val
  350.     lappend val " " $pvalue
  351.     set pvalue ""
  352. }
  353.  
  354. # marks
  355. proc css::GetPropertiesmarks {prop pval v} {
  356.     upvar $pval pvalue $v val
  357.     css::GetChoicesProp none pvalue val
  358.     lappend val [regsub -nocase {(^|[ \t\r\n])crop($|[ \t\r\n])} $pvalue "" pvalue]
  359.     lappend val [regsub -nocase {(^|[ \t\r\n])cross($|[ \t\r\n])} $pvalue "" pvalue]
  360. }
  361.  
  362. # page
  363. proc css::GetPropertiespage {prop pval v} {
  364.     upvar $pval pvalue $v val
  365.     if {[string tolower [lindex $pvalue 0]] == "auto"} {
  366.         lappend val 1
  367.         set pvalue [lrange $pvalue 1 end]
  368.     } else {
  369.         lappend val 0
  370.         lappend val $pvalue
  371.         if {[regexp {^[^-0-9][^ \t\r\n]*$} $pvalue]} {
  372.             set pvalue ""
  373.         }
  374.     }
  375. }
  376.  
  377. # backpos
  378. proc css::GetPropertiesbackpos {prop pval v} {
  379.     upvar $pval pvalue $v val
  380.     css::GetChoicesProp "" pvalue val
  381.     foreach bp [list {top center bottom} {left center right}] {
  382.         set found 0
  383.         set nv ""
  384.         foreach v $pvalue {
  385.             if {!$found && [lcontains bp [string tolower $v]]} {
  386.                 lappend val [string tolower $v]
  387.                 set found 1
  388.             } else {
  389.                 lappend nv $v
  390.             }
  391.         }
  392.         if {!$found} {lappend val " "}
  393.         set pvalue $nv
  394.     }
  395.     for {set i 0} {$i < 2} {incr i} {
  396.         set pv [lindex $pvalue $i]
  397.         css::GetNumber $prop pv val length 1 0 0
  398.         lappend newpv $pv
  399.     }
  400.     set pvalue [join [concat $newpv [lrange $pvalue 2 end]]]
  401. }
  402.  
  403. # fontstyle
  404. proc css::GetPropertiesfontstyle {prop pval v} {
  405.     upvar $pval pvalue $v val
  406.     global css::Choices
  407.     set pvalue [string tolower $pvalue]
  408.     if {$pvalue == "all"} {
  409.         lappend val " " "" 0 1
  410.         set pvalue ""
  411.     } else {
  412.         # Special case with font-stretch descriptor
  413.         set ch [set css::Choices($prop)]
  414.         if {$prop == "font-stretch"} {set ch [lrange $ch 2 end]}
  415.         set pvs ""; set err ""
  416.         foreach p [split $pvalue ,] {
  417.             set p [string trim $p]
  418.             if {[lcontains ch $p]} {
  419.                 lappend pvs $p
  420.             } else {
  421.                 lappend err $p
  422.             }
  423.         }
  424.         lappend val " " [join $pvs ", "] 0 0
  425.         set pvalue [join $err]
  426.     }
  427. }
  428.  
  429. # fontvariant
  430. proc css::GetPropertiesfontvariant {prop pval v} {
  431.     upvar $pval pvalue $v val
  432.     global css::Choices
  433.     set pvalue [string tolower $pvalue]
  434.     set pvs ""; set err ""
  435.     foreach p [split $pvalue ,] {
  436.         set p [string trim $p]
  437.         if {[lcontains  css::Choices($prop) $p]} {
  438.             lappend pvs $p
  439.         } else {
  440.             lappend err $p
  441.         }
  442.     }
  443.     lappend val " " [join $pvs ", "] 0
  444.     set pvalue [join $err]
  445. }
  446.  
  447. # fontsize
  448. proc css::GetPropertiesfontsize {prop pval v} {
  449.     upvar $pval pvalue $v val
  450.     set pvalue [string tolower $pvalue]
  451.     if {$pvalue == "all"} {
  452.         lappend val "" " " 1 ""
  453.         set pvalue ""
  454.     } else {
  455.         set pvs ""; set err ""
  456.         foreach p [split $pvalue ,] {
  457.             set p [string trim $p]
  458.             if {![catch {css::CheckNumber $prop length $p "" 0 0 0}]} {
  459.                 lappend pvs $p
  460.             } else {
  461.                 lappend err $p
  462.             }
  463.         }
  464.         if {$pvs != ""} {
  465.             regexp {([0-9]+)([^0-9]+)} [lindex $pvs 0] "" n u
  466.             lappend val $n $u
  467.         } else {
  468.             lappend val "" " "
  469.         }
  470.         lappend val 0 [join [lrange $pvs 1 end] ", "]
  471.         set pvalue [join $err]
  472.     }
  473. }
  474.  
  475. # panose
  476. proc css::GetPropertiespanose {prop pval v} {
  477.     upvar $pval pvalue $v val
  478.     if {$pvalue != "" && [llength $pvalue] != 10} {return}
  479.     set nv ""
  480.     foreach v $pvalue {
  481.         css::GetNumberNoUnit $prop v val 0 1
  482.         if {$v != ""} {lappend nv $v}
  483.     }
  484.     set pvalue $nv
  485. }
  486.  
  487. # widths
  488. proc css::GetPropertieswidths {prop pval v} {
  489.     upvar $pval pvalue $v val
  490.     set vlist [split $pvalue ,]
  491.     set err ""; set vv ""
  492.     foreach u $vlist {
  493.         set e 0
  494.         set ur [lindex [string trim $u] 0]
  495.         if {![css::CheckUrange $ur] && ![regexp {^[0-9]+$} $ur]} {
  496.             set e 1
  497.             lappend err $ur
  498.         } 
  499.         foreach n [lrange $u 1 end] {
  500.             if {![regexp {^[0-9]+$} $n]} {lappend err $n}
  501.         }
  502.         append vv ", [string trim $u]"
  503.         if {!$e && [llength $u] == 1 && ![regexp {^[0-9]+$} $ur]} {
  504.             lappend err $u
  505.         }
  506.     }
  507.     lappend val [string trimleft $vv ", "]
  508.     set pvalue [join $err]
  509. }
  510.  
  511. # bbox
  512. proc css::GetPropertiesbbox {prop pval v} {
  513.     upvar $pval pvalue $v val
  514.     set n 0
  515.     set nv ""
  516.     foreach num [split $pvalue ,] {
  517.         set num [string trim $num]
  518.         css::GetNumberNoUnit $prop num val 0 1
  519.         if {$num != ""} {lappend nv $num}
  520.         incr n
  521.     }
  522.     for {set i $n} {$i < 4} {incr i} {
  523.         lappend val ""
  524.     }
  525.     set pvalue $nv
  526. }
  527.  
  528. # unirange
  529. proc css::GetPropertiesunirange {prop pval v} {
  530.     upvar $pval pvalue $v val
  531.     set vlist [split $pvalue ,]
  532.     set err ""; set vv ""
  533.     foreach u $vlist {
  534.         if {![css::CheckUrange [string trim $u]]} {
  535.             lappend err $u
  536.         } else {
  537.             append vv ", [string trim $u]"
  538.         }
  539.     }
  540.     lappend val [string trimleft $vv ", "]
  541.     set pvalue [join $err]
  542. }
  543.  
  544. # src
  545. proc css::GetPropertiessrc {prop pval v} {
  546.     upvar $pval pvalue $v val
  547.     lappend val "" " " 0 "" "" 0
  548.     set src [set src0 [string trim $pvalue]]
  549.     if {$src == ""} {return}
  550.     while {[regsub -nocase {^((url\([ \t\r\n]*("[^"]+"|'[^']+'|[^"' \t\r\n]+)[ \t\r\n]*\)[ \t\r\n]*format\(("[^"]+"|'[^']+')([ \t\r\n]*,[ \t\r\n]("[^"]+"|'[^']+'))*\))|local\(("[^"]+"|'[^']+')\)),?[ \t\r\n]*} $src "" src]} {
  551.     }
  552.     set pvalue $src
  553.     lappend val $src0
  554. }
  555.  
  556. # textalign
  557. proc css::GetPropertiestextalign {prop pval v} {
  558.     upvar $pval pvalue $v val
  559.     if {[regexp {^("[^"]+"|'[^']+')$} $pvalue]} {
  560.         lappend val " " $pvalue
  561.         set pvalue ""
  562.     } else {
  563.         css::GetPropertieschoices $prop pvalue val
  564.         lappend val ""
  565.     }
  566. }
  567.  
  568. # textdecoration
  569. proc css::GetPropertiestextdecoration {prop pval v} {
  570.     upvar $pval pvalue $v val
  571.     global css::Choices
  572.     css::GetChoicesProp none pvalue val
  573.     set pvalue [string tolower $pvalue]
  574.     foreach c [set css::Choices($prop)] {
  575.         if {[set i [lsearch -exact $pvalue $c]] >= 0} {
  576.             lappend val 1
  577.             set pvalue [lreplace $pvalue $i $i]
  578.         } else {
  579.             lappend val 0
  580.         } 
  581.     }
  582. }
  583.  
  584. # textshadow
  585. proc css::GetPropertiestextshadow {prop pval v} {
  586.     upvar $pval pvalue $v val
  587.     if {[set pp [string tolower $pvalue]] == "inherit" || $pp == "none"} {
  588.         lappend val $pp
  589.         set pvalue ""
  590.         return
  591.     }
  592.     set pv ""
  593.     set err ""
  594.     foreach p [split $pvalue ,] {
  595.         set c ""
  596.         if {![catch {css::CheckColorNumber [lindex $p 0]} c0]} {
  597.             set p [lrange $p 1 end]
  598.             set c $c0
  599.         } elseif {![catch {css::CheckColorNumber [lindex $p end]} c0]} {
  600.             set p [lrange $p 0 [expr {[llength $p] - 2}]]
  601.             set c $c0
  602.         }
  603.         set p0 ""
  604.         set e ""
  605.         set i -1
  606.         foreach p1 $p {
  607.             if {![catch {css::CheckNumber [lindex {horizontal vertical blur} [incr i]] length $p1 "" 0 0 0} n]} {
  608.                 lappend p0 $n
  609.             } else {
  610.                 lappend e $p1
  611.             }
  612.         }
  613.         set p $p0
  614.         if {$c != ""} {lappend p $c}
  615.         if {$p != ""} {append pv ", $p"}
  616.         if {$e != ""} {lappend err $e}
  617.     }
  618.     lappend val " " "" "" "" "" "" "" "" " " 0 0 [string trim $pv ", "]
  619.     set pvalue [join $err]
  620. }
  621.  
  622. # borderspacing
  623. proc css::GetPropertiesborderspacing {prop pval v} {
  624.     upvar $pval pvalue $v val
  625.     css::GetChoicesProp "" pvalue val
  626.     for {set i 0} {$i < 2} {incr i} {
  627.         set pv [lindex $pvalue $i]
  628.         css::GetNumber $prop pv val length 0 0 0
  629.         lappend newpv $pv
  630.     }
  631.     set pvalue [join [concat $newpv [lrange $pvalue 2 end]]]
  632. }
  633.  
  634. # cursor
  635. proc css::GetPropertiescursor {prop pval v} {
  636.     upvar $pval pvalue $v val
  637.     global css::Choices
  638.     set vlist [split $pvalue ,]
  639.     set pvalue ""
  640.     set eurl ""
  641.     lappend val "" " " 0
  642.     for {set i 0} {$i < [expr {[llength $vlist] - 1}]} {incr i} {
  643.         set tmp ""
  644.         set u [lindex $vlist $i]
  645.         css::GetUrlProp u tmp
  646.         if {[lindex $tmp 1] != " "} {append eurl ", url(\"[lindex $tmp 1]\")"}
  647.         append pvalue $u
  648.     }
  649.     lappend val [string trimleft $eurl ", "] 0
  650.     set c [string trim [lindex $vlist end]]
  651.     css::GetChoicesProp [set css::Choices($prop)] c val
  652.     append pvalue $c
  653. }
  654.  
  655. # playduring
  656. proc css::GetPropertiesplayduring {prop pval v} {
  657.     upvar $pval pvalue $v val
  658.     css::GetPropertiesuc $prop pvalue val
  659.     set pvalue [string tolower $pvalue]
  660.     lappend val [regsub -nocase {(^|[ \t\r\n])mix($|[ \t\r\n])} $pvalue "" pvalue]
  661.     lappend val [regsub -nocase {(^|[ \t\r\n])repeat($|[ \t\r\n])} $pvalue "" pvalue]
  662. }
  663.  
  664. # azimuth
  665. proc css::GetPropertiesazimuth {prop pval v} {
  666.     upvar $pval pvalue $v val
  667.     css::GetNumChoices $prop pvalue val angle 0 0 0
  668.     set pvalue [string tolower $pvalue]
  669.     foreach c {left-side far-left left center-left center center-right right far-right right-side} {
  670.         if {[set i [lsearch -exact $pvalue $c]] >= 0} {
  671.             lappend val $c
  672.             set pvalue [lreplace $pvalue $i $i]
  673.             break
  674.         }
  675.     }
  676.     if {$pvalue == "behind"} {
  677.         lappend val 1
  678.         set pvalue ""
  679.     } else {
  680.         lappend val 0
  681.     }
  682. }
  683.  
  684. #===============================================================================
  685. # ◊◊◊◊ Getting properties help procs ◊◊◊◊ #
  686. #===============================================================================
  687.  
  688. proc css::GetChoicesProp {items pval v} {
  689.     upvar $pval pvalue $v val
  690.     global css::IsDescriptor
  691.     if {${css::IsDescriptor} && ![llength $items]} {return}
  692.     if {!${css::IsDescriptor}} {lappend items inherit}
  693.     if {[set i [lsearch -exact $items [string tolower $pvalue]]] >= 0} {
  694.         if {[llength $items] == 1} {
  695.             lappend val 1
  696.         } else {
  697.             lappend val [lindex $items $i]
  698.         }
  699.         set pvalue ""
  700.     } elseif {[llength $items] == 1} {
  701.         lappend val 0
  702.     } else {
  703.         lappend val " "
  704.     }
  705. }
  706.  
  707. proc css::GetColorProp {pval v} {
  708.     upvar $pval pvalue $v val
  709.     global html::userColorname html::ColorNumber html::ColorName css::Colors
  710.     
  711.     if {[catch {css::CheckColorNumber $pvalue} tv]} {
  712.         lappend val "" " " 0
  713.     } else {
  714.         if {[set c1 [info exists html::userColorname($tv)]]} {set tv [set html::userColorname($tv)]}
  715.         if {[info exists html::ColorNumber($tv)]} {set tv [set html::ColorNumber($tv)]}
  716.          if {$c1 || [info exists html::ColorName($tv)] || [lcontains css::Colors $tv]} {
  717.             lappend val "" $tv 0
  718.         } else {
  719.             lappend val $tv " " 0
  720.         }
  721.         set pvalue ""
  722.     }
  723. }
  724.  
  725. proc css::GetUrlProp {pval v} {
  726.     upvar $pval pvalue $v val
  727.     if {[regexp -nocase -indices {url\([ \t\r\n]*("[^"]+"|'[^']+'|[^ "'\t\n\r\)]+)[ \t\r\n]*\)} $pvalue url tv]} {
  728.         set tv [html::URLunEscape [string trim [string range $pvalue [lindex $tv 0] [lindex $tv 1]] {"'}]]
  729.         html::AddToCache URLs $tv
  730.         lappend val "" $tv 0
  731.         set pvalue "[string range $pvalue 0 [expr {[lindex $url 0] - 1}]][string range $pvalue [expr {[lindex $url 1] + 1}] end]"
  732.     } else {
  733.         lappend val "" " " 0
  734.     }
  735. }
  736.  
  737. proc css::GetNumberNoUnit {prop pval v percent integer} {
  738.     upvar $pval pvalue $v val
  739.     if {![catch {css::CheckNumber $prop "" $pvalue " " $percent 1 $integer} res]} {
  740.         lappend val $res
  741.         set pvalue ""
  742.     } else {
  743.         lappend val ""
  744.     }
  745. }
  746.  
  747. proc css::GetNumChoices {prop pval v type percent number integer} {
  748.     upvar $pval pvalue $v val
  749.     global css::Choices
  750.     css::GetChoicesProp [set css::Choices($prop)] pvalue val
  751.     css::GetNumber $prop pvalue val $type $percent $number $integer
  752. }
  753.  
  754. proc css::GetNumber {prop pval v type percent number integer} {
  755.     upvar $pval pvalue $v val
  756.     set unit ""
  757.     if {$number} {set unit " "}
  758.     if {![catch {css::CheckNumber $prop $type $pvalue $unit $percent $number $integer} res]} {
  759.         regexp {^([-\+]?[0-9]+\.?[0-9]*)([%a-zA-Z]*)$} $res "" n u
  760.         lappend val $n $u
  761.         set pvalue ""
  762.     } else {
  763.         lappend val "" ""
  764.     }
  765. }
  766.  
  767.